﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
		<title>Repositories</title>
		<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
	</head>

	<body>

		<div class="document-contents">

			<p>
    &quot;<em>Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects</em>&quot; (Martin Fowler).</p>
			<p>
    Repositories, in practice, are used to perform database operations for 
	domain objects (<a href="/Pages/Documents/Entities">Entity</a> and Value types). 
	Generally, a seperated repository is used for each Entity (or Aggregate 
	Root).</p>
			<h3 id="DocIRepositoryClasses">
    		Default Repositories</h3>
			<p>
    In ASP.NET Boilerplate, a repository classes implement <strong>IRepository&lt;TEntity, 
			TPrimaryKey&gt;</strong> interface. ABP can automatically creates 
			default repositories for each entity type. You can directly <a href="/Pages/Documents/Dependency-Injection">inject</a> 
				<strong>IRepository&lt;TEntity&gt;</strong> (or IRepository&lt;TEntity, TPrimaryKey&gt;). An example
				<a href="/Pages/Documents/Application-Services">application service</a> uses a 
repository to insert an entity to database:</p>
			<pre lang="cs">public class PersonAppService : IPersonAppService
{
    <strong>private readonly IRepository&lt;Person&gt; _personRepository;</strong>

    public PersonAppService(<strong>IRepository&lt;Person&gt; personRepository</strong>)
    {
        _personRepository = personRepository;
    }

    public void CreatePerson(CreatePersonInput input)
    {        
        person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
        <strong>_personRepository.Insert(person);</strong>
    }
}</pre>
			<p>PersonAppService contructor-injects <strong>IRepository&lt;Person&gt;</strong> and 
uses the <strong>Insert</strong> method.</p>
			<h3>Custom Repositories</h3>
			<p>You only create a 
repository class for an entity when you need to create a custom repository 
method(s) for that entity.</p>
			<h4>Custom Repository Interface</h4>
			<p>
    A repository definition for a Person entity is shown below:</p>
			<pre lang="cs">public interface IPersonRepository : IRepository&lt;Person&gt;
{

}</pre>
			<p>
    IPersonRepository extends <strong>IRepository&lt;TEntity&gt;</strong>. It's used 
	to define entities which has a primary key type of int (Int32). If your 
	entity's primary key is not int, you can extend <strong>IRepository&lt;TEntity, 
	TPrimaryKey&gt;</strong> interface as shown below:</p>
			<pre lang="cs">public interface IPersonRepository : IRepository&lt;Person, long&gt;
{

}</pre>
			<h4>
    		Custom Repository Implementation</h4>

			<p>ASP.NET Boilerplate is designed to be independent from a 
			particular ORM (Object/Relational Mapping) framework or another 
			technique to access to database. Repositories are implemented in <strong>NHibernate</strong> and <strong>
EntityFramework</strong> as out-of-the-box. See documents to implement 
repositories in ASP.NET Boilerplate in these frameworks:</p>
			<ul>
				<li>
					<a href="/Pages/Documents/NHibernate-Integration">NHibernate integration</a>
				</li>
				<li>
					<a href="/Pages/Documents/EntityFramework-Integration">EntityFramework integration</a>
				</li>
			</ul>

			<h3>Base Repository Methods</h3>
			<p>Every repository has some common methods coming from 
			IRepository&lt;TEntity&gt; interface. We will investigate most of them 
			here.</p>
			<h4 id="DocQuerying">
    Querying</h4>
			<h5 id="DocGettingSingleEntity">
    Getting single entity</h5>

			<pre lang="cs">TEntity Get(TPrimaryKey id);
Task&lt;TEntity&gt; GetAsync(TPrimaryKey id);
TEntity Single(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
Task&lt;TEntity&gt; SingleAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
TEntity FirstOrDefault(TPrimaryKey id);
Task&lt;TEntity&gt; FirstOrDefaultAsync(TPrimaryKey id);
TEntity FirstOrDefault(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
Task&lt;TEntity&gt; FirstOrDefaultAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
TEntity Load(TPrimaryKey id);</pre>

			<p>
				<strong>Get </strong>method is used to get an Entity with given primary key 
(Id). It throws exception if there is no entity in database with given Id.
				<strong>Single</strong> method is similar to Get but takes an expression rather 
than an Id. So, you can write a lambda expression to get an Entity. Example 
usages:</p>
			<pre>var person = _personRepository.Get(42);
var person = _personRepository.Single(p =&gt; p.Name == "John");</pre>
			<p>Notice that <strong>Single </strong>method throws 
exception if there is no entity with given conditions or there are more 
than one entity.</p>
			<p>
				<strong>FirstOrDefault </strong>is similar but returns <strong>null</strong> 
(instead of throwing exception)
if there is no entity with given Id or expression. Returns first found entity if 
there are more than one entity for given conditions.</p>
			<p>
				<strong>Load </strong>does not retrieves entity from database but creates a 
proxy object for lazy loading. If you only use Id property, Entity is not 
actually retrieved. It's retrieved from database only if you access to other 
properties of entity. This can be used instead of Get, for performance reasons. 
It's implemented in <strong>NHibernate</strong>. If ORM provider does not implements it, Load 
method works as identical as Get method.</p>

			<h5 id="DocGettingListOfEntities">Getting a list of entities</h5>

			<pre>List&lt;TEntity&gt; GetAllList();
Task&lt;List&lt;TEntity&gt;&gt; GetAllListAsync();
List&lt;TEntity&gt; GetAllList(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
Task&lt;List&lt;TEntity&gt;&gt; GetAllListAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
IQueryable&lt;TEntity&gt; GetAll();</pre>
			<p>
				<strong>GetAllList </strong>is used to retrieve all entities from database. 
	Overload of it can be used to filter entities. Examples:</p>
			<pre lang="cs">var allPeople = _personRepository.GetAllList();
var somePeople = _personRepository.GetAllList(person => person.IsActive &amp;&amp; person.Age &gt; 42);</pre>
			<p>
				<strong>GetAll</strong> returns IQueryable&lt;T&gt;. So, you 
	can add Linq methods after it. Examples:</p>
			<pre lang="cs">//Example 1
var query = from person in _personRepository.GetAll()
            where person.IsActive
            orderby person.Name
            select person;
var people = query.ToList();

//Example 2:
List&lt;Person&gt; personList2 = _personRepository.GetAll().Where(p =&gt; p.Name.Contains("H")).OrderBy(p =&gt; p.Name).Skip(40).Take(20).ToList();</pre>

			<p>With using GetAll, almost all queries can be written in Linq. Even it can be used in 
a join expression.</p>
			<div class="bs-callout bs-callout-warning">
				<h4>About IQueryable&lt;T&gt;</h4>
				<p>When you call GetAll() out of a repository method, there must be an open database 
	connection. This is because of deferred execution of IQueryable&lt;T&gt;. It 
	does not perform database query unless you call ToList() method or use the 
	IQueryable&lt;T&gt; in a foreach loop (or somehow access to queried items). 
	So, 
	when you call ToList() method, database connection must be alive. For a web 
				application, you don't care about that in most cases since MVC 
				controller methods are unit of work by default and database 
				connection is available for entire request. See <strong>
						<a href="/Pages/Documents/Unit-Of-Work">UnitOfWork</a></strong> 
				documentation to understand it better.</p>
			</div>

			<h5 id="DocGettingCustom">Custom return value</h5>
			<p>There is also an additional method to provide power of IQueryable 
			that can be usable out of a unit of work.</p>

			<pre lang="cs">T Query&lt;T&gt;(Func&lt;IQueryable&lt;TEntity&gt;, T&gt; queryMethod);</pre>

			<p>Query method accepts a lambda (or method) that recieves 
IQueryable&lt;T&gt; and returns any type of object. Example:</p>
			<pre lang="cs">var people = _personRepository.Query(q =&gt; q.Where(p =&gt; p.Name.Contains("H")).OrderBy(p =&gt; p.Name).ToList());</pre>

			<p>Since 
given lamda (or method) is executed inside the repository method, it's executed when 
database connection is available. You can return a list of entities, a single entity, 
a projection or something else that executes the query.</p>
			<h4 id="DocInsertEntity">Insert</h4>
			<p>IRepository interface defines methods to insert an entity to database:</p>
			<pre lang="cs">TEntity Insert(TEntity entity);
Task&lt;TEntity&gt; InsertAsync(TEntity entity);
TPrimaryKey InsertAndGetId(TEntity entity);
Task&lt;TPrimaryKey&gt; InsertAndGetIdAsync(TEntity entity);
TEntity InsertOrUpdate(TEntity entity);
Task&lt;TEntity&gt; InsertOrUpdateAsync(TEntity entity);
TPrimaryKey InsertOrUpdateAndGetId(TEntity entity);
Task&lt;TPrimaryKey&gt; InsertOrUpdateAndGetIdAsync(TEntity entity);</pre>
			<p>
				<strong>Insert</strong> method simply inserts new entity to database and 
returns the same inserted entity. <strong>InsertAndGetId</strong> method returns 
Id of new inserted entity. This is useful if Id is auto increment and you need 
Id of the new inserted entity. <strong>InsertOrUpdate</strong> inserts or updated given 
entity by checking it's Id's value. Lastly, <strong>InsertOrUpdateAndGetId</strong> 
returns Id of the entity after inserting or updating.</p>
			<h4 id="DocUpdateEntity">Update</h4>
			<p>IRepository defines methods to update an existing entity in the database. It 
gets the entity to be updated and returns the same entity object.</p>
			<pre>TEntity Update(TEntity entity);
Task&lt;TEntity&gt; UpdateAsync(TEntity entity);</pre>
<p>Most of times you don't need to explicitly call Update methods since unit of 
work system automatically saves all changes when unit of work completes. See
<a href="Unit-Of-Work.html">unit of work</a> documentation for more.</p>
			<h4 id="DocDeleteEntity">Delete</h4>
			<p>IRepository defines methods to delete an existing entity from the database</p>

			<pre>void Delete(TEntity entity);
Task DeleteAsync(TEntity entity);
void Delete(TPrimaryKey id);
Task DeleteAsync(TPrimaryKey id);
void Delete(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
Task DeleteAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);</pre>
			<p>First method accepts an existing entity, second one accepts Id of the entity 
to delete. The last one accepts a condition to delete all entities fit to given 
condition. Notice that all entities matches given predicate may be retrived 
from database and then deleted (based on repository implementation). So, use it carefully, it may cause performance 
problems if there are too many entities with given condition.</p>

			<h4 id="DocOtherRepositoryMethods">Others</h4>
			<p>IRepository also provides methods to get count of entities in a table.</p>
			<pre>int Count();
Task&lt;int&gt; CountAsync();
int Count(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
Task&lt;int&gt; CountAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
long LongCount();
Task&lt;long&gt; LongCountAsync();
long LongCount(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
Task&lt;long&gt; LongCountAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);</pre>

			<h4 id="DocAboutAsyncMethods">About Async Methods</h4>

			<p>ASP.NET Boilerplate supports async programming model. So, repository methods 
has Async versions. Here, a sample 
				<a href="/Pages/Documents/Application-Services">application service</a> method that uses async model:</p>
			<pre lang="cs">public class PersonAppService : AbpWpfDemoAppServiceBase, IPersonAppService
{
    private readonly IRepository&lt;Person&gt; _personRepository;

    public PersonAppService(IRepository&lt;Person&gt; personRepository)
    {
        _personRepository = personRepository;
    }

    public async Task&lt;GetPeopleOutput&gt; GetAllPeople()
    {
        var people = await _personRepository.GetAllListAsync();

        return new GetPeopleOutput
        {
            People = Mapper.Map&lt;List&lt;PersonDto&gt;&gt;(people)
        };
    }
}</pre>
			<p>GetAllPeople method is async and uses GetAllListAsync with await keyword.</p>
			<p>Async may not be supported by all ORM frameworks. It's supported by 
EntityFramework. If not supported, Async repository methods works synchronously. 
Also, for example, InsertAsync works same as Insert in EntityFramework since EF 
does not write new entities to database until unit of work completes 
(a.k.a. DbContext.SaveChanges).</p>

			<h3 id="DocManageConnection">Managing Database Connection</h3>
			<p>A database 
connection is not opened or closed in a repository method. Connection management is made automatically 
by ASP.NET Boilerplate.</p>
			<p>A database connection is <strong>opened </strong>and a <strong>transaction
				</strong>begins while entering a repository method automatically. When the 
method ends and returns, all changes are <strong>saved</strong>, transaction is <strong>commited
				</strong>and database connection is <strong>closed </strong>automatically by 
ASP.NET Boilerplate. If your repository method throws any type of Exception, the 
transaction is automatically <strong>rolled back </strong>and database 
connection is closed. This is true for all public methods of classes those 
implement IRepository interface.</p>
			<p>If a repository method calls to another repository method (even a method of 
different repository) they share same connection and transaction. Connection is 
managed (opened/closed) by the first method that enters a repository. For more 
information on database connection management, see
				<a href="/Pages/Documents/Unit-Of-Work">UnitOfWork</a> documentation.</p>
			<h3 id="DocRepositoryLifecycle">Lifetime of a Repository</h3>
			<p>All repository instances are <strong>Transient</strong>. It 
			means, they are instantiated per usage. See
				<a href="/Pages/Documents/Dependency-Injection">Dependency Injection</a> 
documentation for more information.</p>

			<h3 id="DocRepositoryBestPractices">Repository Best Practices</h3>
			<ul>
				<li>For an entity of T, use IRepository&lt;T&gt; wherever it's possible. Don't 
	create custom repositories unless it's really needed. Pre-defined repository 
	methods will be enough for many cases.</li>
				<li>If you are creating a custom repository (by extending 
	IRepository&lt;TEntity&gt;);<ul>
						<li>Repository classes should be stateless. That means, you should not 
		define repository-level state objects and a repository method call 
		should not effect another call.</li>
						<li>Custom repository methods should not contain business logic or 
		application logic. It should just perform data-related or orm-specific 
		tasks.</li>
						<li>While repositories can use dependency injection, define less or no 
		dependency to other services.</li>
					</ul>
				</li>
			</ul>
		</div>
	</body>

</html>
